package com.craftworks.driver.bluetop;

/**
 * 蓝拓扑播发卡驱动适配器（JNI）,
 * 仅针对 BSTC-12 V5 PCI 板卡，驱动版本：6.2.301。
 *
 * <p>除devcnt外的所有接口，均”一对一“转接原始API。
 *
 * <p>[使用说明]
 * <pre>
 * 1、JNI实现的编译链接注意事项
 *    该版本驱动采用VC6.0编译，在VS2005及以上版本中调用时，需对JNI工程添加
 *    链接器忽略指令（/NODEFAULTLIB），声明忽略libcd库（该库为VS2003及以下
 *    版本编译链接时使用，现已失效）。
 *    设置位置：项目属性页（项目->属性（Alt-F7））-> 配置属性 -> 链接器 -> 输入
 *              -> 忽略特定默认库 -> 填写“libcd”
 *
 * 2、接口调用顺序
 *    该版本所有接口仅针对“已打开”设备，而非“已插入”设备。因此，类似“查询驱动版本”
 *    这样看似与设备无关的操作，也需要先打开设备。
 *    正确的操作顺序：打开卡片（open|bst_init）-> 执行操作 -> 关闭卡片（close|bst_fini）
 *    推论（未经蓝拓扑方面证实，也未进行实际测试）：如果同时插入两块不同版本的卡片，
 *    有可能产生兼容性问题。
 *
 * 3、目前没有直接的查询已插入设备数量的方法
 *    蓝拓扑方面表示他们的驱动接口是面向逻辑操作，而非物理设备的，因此，没有提供
 *    单一方法查询物理设备。此版驱动最大支持八块卡（SDK文档中约定），猜测是驱动
 *    维护了一个静态的设备数组，然后通过开闭设备操作将打开的设备句柄保存到数组
 *    空位中，所谓的device_id实际是这个数组的索引。
 *
 *    上述猜测可以通过下面的操作来验证：
 *      (1) 插入多块卡，比如3块（id为0、1、2）。
 *      (2) 全部打开，然后关闭中间序号的卡（id为1）。
 *      (3) 操作剩余卡片，但不关闭。
 *      (4) 使用原序号再次打开被关闭的卡（id=2）。
 *      (5) 关闭所有卡。
 *    如果上述操作均成功，说明上述推论正确，device_id就是内部数组的索引。
 *
 *    另外，可以通过循环打开卡设备来测试当前的插卡数量（同样面临版本兼容性问题）。
 * </pre>
 * @author yeweibin
 */
public final class BSTC12V5Adapter
{
    private BSTC12V5Adapter() {}

    public static final int MAX_SUPPORTED_DEVICE_COUNT = 8;

    public static native boolean    open(int id);
    public static native boolean    close(int id);
    public static native boolean    setup(int id, long bitrate, int frameSize,
                                          int outputMode, boolean enableASIBurstMode,
                                          boolean enableInputReferenceClock,
                                          boolean enableOutputReferenceClock);
    public static native int        send(int id, byte[] data, int offset, int length);
    public static native int        flush(int id);
    public static native boolean    finish(int id);

    public static native long       version(int id);
    public static native long       capacity(int id);
    public static native long       amount(int id);

    // 尚不明确此接口的确切含义
    public static native long       devnum(int id);

    // 测试接口，非蓝拓扑提供
    public static native long       devcnt();

    public static boolean isAcceptableDeviceID(int id)
    {
        return (0 <= id && id < MAX_SUPPORTED_DEVICE_COUNT);
    }
}
